package com.polaris.live.utils

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.polaris.live.common.util.LogExt
import com.polaris.live.common.util.StructUtils
import com.polaris.live.common.util.computeIfAbsentBy21
import java.util.concurrent.ConcurrentHashMap

/**
 * LifecycleListenerDispatcher
 *
 * @author Created by lucas on 2023/10/21 15:55
 * @since 1.0.0
 */
abstract class AbstractLifecycleListenerDispatcher<L>(
    private val tag: String
) {

    /**
     * 添加消息接收监听
     */
    fun observe(owner: LifecycleOwner, l: L): Boolean {
        if (owner.lifecycle.currentState == Lifecycle.State.DESTROYED) {
            return false
        }

        addListener(l)

        owner.lifecycle.addObserver(object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    removeListener(l)

                    LogExt.logI("LifecycleListenerDispatcher") {
                        "$tag observe remove: ${owner::class.simpleName}, size = ${getListenerSize()}"
                    }
                }
            }
        })

        LogExt.logI("LifecycleListenerDispatcher") {
            "$tag observe add: ${owner::class.simpleName}, size = ${getListenerSize()}"
        }

        return true
    }

    protected abstract fun getListenerSize(): Int

    protected abstract fun addListener(l: L)

    protected abstract fun removeListener(l: L)

}

class LifecycleListenerDispatcher<L>(tag: String = "") : AbstractLifecycleListenerDispatcher<L>(tag) {

    protected val lifecycleListeners = StructUtils.newSaleSet<L>()

    val listeners: Set<L>
        get() = lifecycleListeners

    override fun getListenerSize(): Int = lifecycleListeners.size

    override fun addListener(l: L) {
        lifecycleListeners.add(l)
    }

    override fun removeListener(l: L) {
        lifecycleListeners.remove(l)
    }

}

class MapLifecycleListenerDispatcher<L : MapLifecycleListener>(
    tag: String = ""
) : AbstractLifecycleListenerDispatcher<L>(tag) {

    private val lifecycleListeners = ConcurrentHashMap<String, MutableSet<L>>()

    private fun getListeners(l: L): MutableSet<L> {
        return lifecycleListeners.computeIfAbsentBy21(l.key) {
            StructUtils.newSaleSet()
        }
    }

    override fun getListenerSize(): Int = lifecycleListeners.size

    override fun addListener(l: L) {
        getListeners(l).add(l)
    }

    override fun removeListener(l: L) {
        getListeners(l).remove(l)
    }

    fun getListener(key: String): Set<L> {
        return lifecycleListeners[key] ?: emptySet()
    }
}

abstract class MapLifecycleListener {

    abstract val key: String

}